<template>
  <BasicModal
    @register="register"
    title="添加键名筛选器"
    @ok="conditionOut"
    :destroyOnClose="true"
    :closeFunc="close"
    :body-style="{ marginLeft: '10px', marginRight: '10px' }"
    width="600px"
  >
    <div class="flex flex-row items-center">
      <Select class="!w-full !mr-20px" v-model:value="conditionItem.key.type" :disabled="isDisable">
        <SelectOption value="ATTRIBUTE">属性</SelectOption>
        <SelectOption value="TIME_SERIES">Timeseries</SelectOption>
        <SelectOption value="CONSTANT">常量</SelectOption>
      </Select>

      <AutoComplete
        class="!w-full !mr-20px"
        placeholder="键名"
        v-model:value="conditionItem.key.key"
        v-show="conditionItem.key.type === 'ATTRIBUTE'"
        :options="AttributeList"
        :filter-option="filterOption"
        :disabled="isDisable"
      />
      <AutoComplete
        class="!w-full !mr-20px"
        placeholder="键名"
        v-model:value="conditionItem.key.key"
        v-show="conditionItem.key.type === 'TIME_SERIES'"
        :options="TimeseriesList"
        :filter-option="filterOption"
        :disabled="isDisable"
      />
      <Input
        class="!mr-20px"
        placeholder="键名"
        required
        v-model:value="conditionItem.key.key"
        v-show="conditionItem.key.type === 'CONSTANT'"
        :disabled="isDisable"
      />

      <Select
        class="!w-full"
        placeholder="值类型"
        required
        v-model:value="conditionItem.valueType"
        @change="TypeChange"
        :disabled="isDisable"
      >
        <SelectOption value="STRING">字符串</SelectOption>
        <SelectOption value="NUMERIC">数字</SelectOption>
        <SelectOption value="BOOLEAN">布尔值</SelectOption>
        <SelectOption value="DATE_TIME">日期时间</SelectOption>
      </Select>

      <Input
        placeholder="值"
        v-model:value="conditionItem.value"
        class="!ml-20px"
        v-show="
          conditionItem.key.type === 'CONSTANT' &&
          (conditionItem.valueType === 'STRING' || conditionItem.valueType === 'NUMERIC')
        "
        :disabled="isDisable"
      />

      <Checkbox
        v-model:checked="conditionItem.value"
        class="!ml-20px"
        v-show="conditionItem.key.type === 'CONSTANT' && conditionItem.valueType === 'BOOLEAN'"
        :disabled="isDisable"
        >真</Checkbox
      >

      <DatePicker
        show-time
        placeholder="Select Time"
        class="!ml-20px"
        v-model:value="conditionItem.value"
        valueFormat="x"
        v-if="conditionItem.key.type === 'CONSTANT' && conditionItem.valueType === 'DATE_TIME'"
        :disabled="isDisable"
      />
    </div>
    <Collapse
      expandIconPosition="right"
      :default-active-key="['1']"
      class="!mt-24px"
      v-show="conditionItem.valueType"
    >
      <CollapsePanel header="筛选器" key="1">
        <div class="flex flex-col">
          <Row>
            <Col span="6">
              <span>操作</span>
            </Col>
            <Col span="4">
              <span v-show="conditionItem.valueType === 'STRING'">忽略大小写</span>
            </Col>
            <Col span="10">
              <span>值</span>
            </Col>
          </Row>
          <Divider class="!mb-24px !mt-2px" />
          <div v-show="condition.length === 0" class="text-center"><span>未配置筛选器</span></div>
          <div
            v-for="(cond, index) in condition"
            :key="cond.id"
            class="flex items-center flex-row mb-24px"
          >
            <Select
              class="!w-full !mr-20px"
              v-model:value="cond.predicate.operation"
              v-show="cond.valueType === 'STRING' && cond.predicate.type != 'COMPLEX'"
              :disabled="isDisable"
            >
              <SelectOption value="EQUAL">等于</SelectOption>
              <SelectOption value="NOT_EQUAL">不等于</SelectOption>
              <SelectOption value="STARTS_WITH">开始于</SelectOption>
              <SelectOption value="ENDS_WITH">结束于</SelectOption>
              <SelectOption value="CONTAINS">包含</SelectOption>
              <SelectOption value="NOT_CONTAINS">不包含</SelectOption>
              <SelectOption value="IN">存在</SelectOption>
              <SelectOption value="NOT_IN">不存在</SelectOption>
            </Select>
            <Select
              class="!w-full !mr-20px"
              v-model:value="cond.predicate.operation"
              v-show="
                (cond.valueType === 'NUMERIC' || cond.valueType === 'DATE_TIME') &&
                cond.predicate.type != 'COMPLEX'
              "
              :disabled="isDisable"
            >
              <SelectOption value="EQUAL">等于</SelectOption>
              <SelectOption value="NOT_EQUAL">不等于</SelectOption>
              <SelectOption value="GREATER">大于</SelectOption>
              <SelectOption value="LESS">小于</SelectOption>
              <SelectOption value="GREATER_OR_EQUAL">大于或等于</SelectOption>
              <SelectOption value="LESS_OR_EQUAL">小于或等于</SelectOption>
            </Select>
            <Select
              class="!w-full !mr-20px"
              v-model:value="cond.predicate.operation"
              v-show="cond.valueType === 'BOOLEAN' && cond.predicate.type != 'COMPLEX'"
              :disabled="isDisable"
            >
              <SelectOption value="EQUAL">等于</SelectOption>
              <SelectOption value="NOT_EQUAL">不等于</SelectOption>
            </Select>
            <Checkbox
              v-model:checked="cond.predicate.ignoreCase"
              class="!mr-20px"
              v-show="
                conditionItem.valueType === 'STRING' &&
                cond.predicate?.value?.useDynamic === false &&
                cond.predicate.type != 'COMPLEX'
              "
              :disabled="isDisable"
            />
            <span v-show="cond.predicate.type === 'COMPLEX'">复合筛选器</span>
            <Button
              v-show="cond.predicate.type === 'COMPLEX' && !isDisable"
              size="large"
              shape="circle"
              type="text"
              @click="toEdit(cond, index)"
            >
              <Icon :icon="ICON.EDIT" />
            </Button>
            <Button
              v-show="cond.predicate.type === 'COMPLEX' && isDisable"
              size="large"
              shape="circle"
              type="text"
              @click="toEdit(cond, index)"
            >
              <Icon :icon="ICON.MORE_Vertically" />
            </Button>
            <Input
              v-model:value="cond.predicate.value.defaultValue"
              placeholder="默认值"
              v-if="
                conditionItem.valueType === 'STRING' && cond.predicate?.value?.useDynamic === false
              "
              :disabled="isDisable"
            />
            <InputNumber
              v-model:value="cond.predicate.value.defaultValue"
              placeholder="默认值"
              v-if="
                conditionItem.valueType === 'NUMERIC' && cond.predicate?.value?.useDynamic === false
              "
              :disabled="isDisable"
            />
            <Checkbox
              v-model:checked="cond.predicate.value.defaultValue"
              v-if="
                conditionItem.valueType === 'BOOLEAN' && cond.predicate?.value?.useDynamic === false
              "
              :disabled="isDisable"
              >真</Checkbox
            >
            <DatePicker
              show-time
              placeholder="Select Time"
              v-model:value="cond.predicate.value.defaultValue"
              valueFormat="x"
              v-if="
                conditionItem.valueType === 'DATE_TIME' &&
                cond.predicate?.value?.useDynamic === false
              "
              :disabled="isDisable"
            />
            <Select
              class="!w-full"
              v-model:value="cond.predicate.value.dynamicValue.sourceType"
              placeholder="动态原类型"
              v-if="cond.predicate?.value?.useDynamic === true"
              :disabled="isDisable"
              :allowClear="true"
            >
              <SelectOption value="CURRENT_TENANT">当前租户</SelectOption>
              <SelectOption value="CURRENT_CUSTOMER">当前客户</SelectOption>
              <SelectOption value="CURRENT_DEVICE">当前设备</SelectOption>
            </Select>
            <Input
              placeholder="属性源"
              v-model:value="cond.predicate.value.dynamicValue.sourceAttribute"
              v-if="cond.predicate?.value?.useDynamic === true"
              :disabled="isDisable"
            />
            <Checkbox
              class="!w-full"
              v-if="
                cond.predicate?.value?.useDynamic === true &&
                (cond.predicate.value.dynamicValue.sourceType === 'CURRENT_CUSTOMER' ||
                  cond.predicate.value.dynamicValue.sourceType === 'CURRENT_DEVICE')
              "
              :disabled="isDisable"
              v-model:checked="cond.predicate.value.dynamicValue.inherit"
              >从所有者继承</Checkbox
            >
            <Button
              size="large"
              shape="circle"
              type="text"
              v-show="
                cond.predicate?.value?.useDynamic === false && conditionItem.key.type != 'CONSTANT'
              "
              @click="showDynamic(cond)"
            >
              <Icon :icon="ICON.VARIABLE" />
            </Button>
            <Button
              size="large"
              shape="circle"
              type="text"
              v-show="
                cond.predicate?.value?.useDynamic === true && conditionItem.key.type != 'CONSTANT'
              "
              @click="hidDynamic(cond)"
            >
              <Icon :icon="ICON.NUMBER" />
            </Button>
            <Button
              size="large"
              shape="circle"
              type="text"
              @click="deleteCond(index)"
              v-show="!isDisable"
            >
              <Icon :icon="ICON.X_DELETE" />
            </Button>
          </div>
        </div>

        <Button type="primary" @click="pushCondition" v-show="!isDisable" class="mr-20px"
          >添加</Button
        >
        <Button type="primary" @click="openAddComplex(true, conditionItem)" v-show="!isDisable"
          >添加复合</Button
        >
      </CollapsePanel>
    </Collapse>
  </BasicModal>
  <AddComplex
    @register="registerAddComplex"
    @push-out="getData"
    @edit="editData"
    :disable="isDisable"
  />
</template>

<script lang="ts" setup>
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { nanoid } from 'nanoid';
  import _ from 'lodash';
  import {
    Row,
    Col,
    Select,
    SelectOption,
    Input,
    Checkbox,
    DatePicker,
    Collapse,
    CollapsePanel,
    Divider,
    InputNumber,
    AutoComplete,
    Button,
  } from 'ant-design-vue';
  import { onMounted, ref, watch, inject } from 'vue';
  import { useModal } from '/@/components/Modal';
  import Icon from '/@/components/Icon';
  import { ICON } from '/@/enums/iconEnum';
  import AddComplex from '/@/components/thingsborad/sharedComponents/modules/addDeviceFileModel/Alarm/AddComplex.vue';
  import {
    getAttribute,
    getTimeseries,
  } from '/@/api/thingsborad/profile/deviceProfile/deviceProfile';
  import dayjs from 'dayjs';
  const emit = defineEmits(['push-out', 'edit']);
  const props = defineProps({
    disable: { type: Boolean },
  });
  let isDisable = ref<boolean>(false);
  const { createConfirm } = useMessage();
  const AttributeList = ref<Array<Recordable>>([]);
  const TimeseriesList = ref<Array<Recordable>>([]);
  const condition = ref<any>([]);
  const isEdit = ref<boolean>(false);
  const whoEdit = ref<any>();
  const isEditModel = inject('isEditModel', false);
  const deviceId: Recordable = inject('deviceId', {});
  watch(
    () => props.disable,
    (nVal) => {
      isDisable.value = nVal;
    },
    { immediate: true },
  );
  const { createMessage } = useMessage();
  const [registerAddComplex, { openModal: openAddComplex }] = useModal();
  const [register, { closeModal }] = useModalInner((data) => {
    condition.value = [];
    if (data) {
      isEdit.value = true;
      condition.value = _.cloneDeep(data);
      condition.value.map((cond) => {
        if (cond.predicate.value) {
          if (cond.key.type === 'CONSTANT') {
            cond.predicate.value.useDynamic = true;
          } else {
            cond.predicate.value.useDynamic = false;
          }
          if (!cond.predicate.value.dynamicValue) {
            cond.predicate.value.dynamicValue = {
              sourceType: null,
              sourceAttribute: null,
              inherit: false,
            };
          }
          //日期回显
          if (cond.valueType === 'DATE_TIME' && cond.predicate.value.defaultValue) {
            cond.predicate.value.defaultValue = dayjs.unix(
              cond.predicate.value.defaultValue / 1000,
            );
          }
        } else {
          cond.predicate.predicates.map((item) => {
            if (item.type != 'COMPLEX') {
              if (cond.key.type === 'CONSTANT') {
                item.value.useDynamic = true;
              } else {
                item.value.useDynamic = false;
              }
              if (!item.value.dynamicValue) {
                item.value.dynamicValue = {
                  sourceType: null,
                  sourceAttribute: null,
                  inherit: false,
                };
              }
            }
          });
        }
      });
      conditionItem.value.key = condition.value[0].key;
      conditionItem.value.valueType = condition.value[0].valueType;
      if (conditionItem.value.valueType === 'DATE_TIME') {
        conditionItem.value.value = dayjs.unix(condition.value[0].value / 1000);
      } else {
        conditionItem.value.value = condition.value[0].value;
      }
    }
  });
  const conditionItem = ref<Recordable>({
    id: '',
    key: {
      key: null,
      type: 'ATTRIBUTE',
    },
    predicate: {
      type: '',
      operation: 'EQUAL',
      ignoreCase: false,
      value: {
        defaultValue: null,
        dynamicValue: {
          sourceType: null,
          sourceAttribute: null,
          inherit: false,
        },
        useDynamic: false,
      },
    },
    valueType: null,
    value: null,
  });
  watch(
    () => conditionItem.value.key.key,
    (nVal) => {
      condition.value.map((item) => {
        item.key.key = nVal;
      });
    },
  );
  watch(
    () => conditionItem.value.key.type,
    (nVal) => {
      condition.value.map((item) => {
        item.key.type = nVal;
        if (item.predicate.value) {
          if (nVal === 'CONSTANT') {
            item.predicate.value.useDynamic = true;
          } else {
            item.predicate.value.useDynamic = false;
          }
        } else {
          item.predicate.predicates.map((it) => {
            if (it.value) {
              if (nVal === 'CONSTANT') {
                it.value.useDynamic = true;
              } else {
                it.value.useDynamic = false;
              }
            }
          });
        }
      });
    },
  );
  watch(
    () => conditionItem.value.value,
    (nVal) => {
      condition.value.map((item) => {
        item.value = nVal;
      });
    },
  );
  watch(
    () => conditionItem.value.valueType,
    (nVal) => {
      if (nVal === 'BOOLEAN') {
        conditionItem.value.predicate.value.defaultValue = false;
        conditionItem.value.value = false;
      } else {
        conditionItem.value.predicate.value.defaultValue = null;
      }
    },
  );
  onMounted(async () => {
    let params = {};
    
    if (isEditModel) {
      params = { deviceProfileId: deviceId.value };
    }
    AttributeList.value = [];
    TimeseriesList.value = [];
    try {
      let response = await getAttribute(params);
      AttributeList.value = response.map((item) => ({
        value: item,
        label: item,
      }));
    } catch (error) {}
    try {
      let response = await getTimeseries(params);
      TimeseriesList.value = response.map((item) => ({
        value: item,
        label: item,
      }));
    } catch (error) {}
  });
  function filterOption(input: string, option: any) {
    return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
  }
  function pushCondition() {
    if (
      conditionItem.value.valueType === 'STRING' ||
      conditionItem.value.valueType === 'NUMERIC' ||
      conditionItem.value.valueType === 'BOOLEAN'
    ) {
      conditionItem.value.predicate.type = conditionItem.value.valueType;
    } else if (conditionItem.value.valueType === 'DATE_TIME') {
      conditionItem.value.predicate.type = 'NUMERIC';
    }

    conditionItem.value.id = '';
    conditionItem.value.id = nanoid();
    if (conditionItem.value.key.type != 'CONSTANT') {
      conditionItem.value.predicate.value.useDynamic = false;
    } else {
      conditionItem.value.predicate.value.useDynamic = true;
    }
    condition.value.push(_.cloneDeep(conditionItem.value));
  }
  function showDynamic(data: Recordable) {
    data.predicate.value.useDynamic = true;
  }
  function hidDynamic(data: Recordable) {
    data.predicate.value.useDynamic = false;
  }
  //更改值类型需要清空条件
  function TypeChange() {
    if (condition.value.length > 0) {
      createConfirm({
        iconType: 'info',
        title: '确定要更改键值类型吗',
        content: '如果您确认新的值类型，所有输入的键过滤器将被删除',
        onOk: () => {
          condition.value = [];
        },
      });
    }
  }
  function deleteCond(index: number) {
    condition.value.splice(index, 1);
  }
  function toEdit(data: Recordable, index: number) {
    whoEdit.value = index;
    openAddComplex(true, data);
  }
  function getData(data: Recordable) {
    condition.value.push(_.cloneDeep(data));
  }
  function editData(data: Recordable) {
    condition.value[whoEdit.value] = _.cloneDeep(data);
  }
  async function close() {
    conditionItem.value = {
      id: '',
      key: {
        key: null,
        type: 'ATTRIBUTE',
      },
      predicate: {
        type: '',
        operation: 'EQUAL',
        ignoreCase: false,
        value: {
          defaultValue: null,
          dynamicValue: {
            sourceType: null,
            sourceAttribute: null,
          },
          useDynamic: false,
        },
      },
      valueType: null,
      value: null,
    };
    condition.value = [];
    return true;
  }
  function conditionOut() {
    let hasEmpty = false;
    if (!conditionItem.value.key.key) {
      createMessage.error('键名不能为空');
      hasEmpty = true;
      return;
    }
    if (!condition.value.length) {
      createMessage.error('请添加筛选器');
      hasEmpty = true;
      return;
    }
    if (conditionItem.value.key.type === 'CONSTANT') {
      condition.value.map((item) => {
        if (
          item.predicate.type != 'COMPLEX' &&
          (!item.predicate.value.dynamicValue.sourceAttribute ||
            !item.predicate.value.dynamicValue.sourceType)
        ) {
          createMessage.error('属性源不能为空');
          hasEmpty = true;
          return;
        }
      });
    }
    if (isEdit.value === false) {
      emit('push-out', condition.value);
    } else {
      emit('edit', condition.value);
    }
    if (hasEmpty) {
      return;
    }
    closeModal();
    conditionItem.value = {
      id: '',
      key: {
        key: null,
        type: 'ATTRIBUTE',
      },
      predicate: {
        type: '',
        operation: 'EQUAL',
        ignoreCase: false,
        value: {
          defaultValue: null,
          dynamicValue: {
            sourceType: null,
            sourceAttribute: null,
          },
          useDynamic: false,
        },
      },
      valueType: null,
      value: null,
    };
    condition.value = [];
  }
</script>

<style lang="less" scoped>
  .ant-checkbox-wrapper :deep(span) {
    white-space: nowrap;
  }
</style>
